Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

fix($compile): properly handle directive replace for table elements #3647

Closed
wants to merge 2 commits into from
Closed

fix($compile): properly handle directive replace for table elements #3647

wants to merge 2 commits into from

Conversation

pelme
Copy link
Contributor

@pelme pelme commented Aug 18, 2013

To work around limitations in jqLite, the template snippet is wrapped in
a

element. This does not work for table elements, since they
cannot be constructed inside a div. This patch takes special to properly
wrap caption, thead, tbody, tfoot, tr, th and td in tags that allow them
to be created.

Closes #1459

To work around limitations in jqLite, the template snippet is wrapped in
a <div> element. This does not work for table elements, since they
cannot be constructed inside a div. This patch takes special to properly
wrap caption, thead, tbody, tfoot, tr, th and td in tags that allow them
to be created.

Closes #1459
@pburgmer
Copy link

+1

2 similar comments
@mabuzer
Copy link

mabuzer commented Aug 23, 2013

+1

@ricardo37
Copy link

+1

@bashmish
Copy link

bashmish commented Sep 5, 2013

+1

1 similar comment
@mhallin79
Copy link

+1

@migajek
Copy link

migajek commented Sep 29, 2013

I've recklessly started learning directives from writing the one for table manipularing, and had no idea what was doing wrong until found out things work properly when I replace tr/ths with divs or anything else.

@btford
Copy link
Contributor

btford commented Oct 1, 2013

If this works in jQuery, perhaps it would be better to improve jqLite. @IgorMinar what do you think of this?

@ghost ghost assigned btford Oct 1, 2013
@pelme
Copy link
Contributor Author

pelme commented Oct 1, 2013

This is more of a browser thing, jQuery('<div><tr></tr></div>') does not work either.

It might be possible to do away with the div-wrapping altogether by improving jqLite, though.

@migajek
Copy link

migajek commented Oct 1, 2013

@pelme why would one need to wrap table-only element with div? jQuery('<div><tr></tr></div>') doesn't work, but $('<tr></tr>') does - yet Angular doesn't let me replace <tr my-directive> with another <tr> from template ... so how is it related?

@btford
Copy link
Contributor

btford commented Oct 2, 2013

Punting this to 1.2.1 for now. Will follow with details (spoiler: it's complicated).

@migajek
Copy link

migajek commented Oct 2, 2013

Is there any workaround/dirty fix for that? Or should we just avoid table-related directives until 1.2.1 ?

@IgorMinar
Copy link
Contributor

the problem here is that angular needs to create fragments of dom and the easiest way to do so is via innerHTML. with innerHTML howerver, you need a container to innerHTML the string template into and we use <div> element for that. But because of certain html rules you can't innerHTML certain elements to certain other elements. This is the case with <div> and <tr>. jQuery uses quite a bit of code to overcome this via heuristics, I'm not keen on doing something along those lines in jqLite.

Even if we did, there is still issue with multi-root templates <tr>1</tr><tr>2</tr> which we need to create within some container and as I wrote before, determining what this container should be is tricky.

@migajek
Copy link

migajek commented Oct 22, 2013

Summing up, will this one be kind of wontfix answer? I have seen quite a few table related directives and all of them uses some tricks for overcoming this problem.

@migajek
Copy link

migajek commented Oct 22, 2013

Btw, @IgorMinar if auto-detecting what wrapping tag should be used, how about letting the developer decide? Just add the "templateWrapper" property which defaults to '

', yet the developer could provide other (like table or thead)?

@migajek
Copy link

migajek commented Oct 22, 2013

  • defaults do div tag...

@KendallPark
Copy link

+1

1 similar comment
@marcorinck
Copy link

+1

@ooflorent
Copy link

@btford:
If this works in jQuery, perhaps it would be better to improve jqLite.

I included jQuery 2.0 before angular (so jqLite is replaced by jQuery) and the problem is still there.
This seems to be specific to angular...

@migajek
Copy link

migajek commented Nov 15, 2013

any chances to get this one fixed?

Conflicts:
	test/ng/compileSpec.js
@dalcib
Copy link

dalcib commented Dec 14, 2013

+1

@caitp
Copy link
Contributor

caitp commented Dec 14, 2013

I didn't realize someone else had a patch for this. I think this is okay, but it's possible to move this into a closure so that in the future it might be extended to support other content types (like SVG content, for example). Also, the 'indexOf' strategy could potentially be problematic, as it is very strict --- I think a regexp is probably a nicer way to do this, in terms of being forgiving. My implementation is at #5235

@caitp caitp closed this in 31c450b Feb 14, 2014
khepin pushed a commit to khepin/angular.js that referenced this pull request Feb 19, 2014
If the first element in a template is a <tr>, <th>, <td>, or <tbody> tag,
the HTML compiler will ensure that the template is wrapped in a <table>
element so that the table content is not discarded.

Closes angular#2848
Closes angular#1459
Closes angular#3647
Closes angular#3241
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Directive fails to insert/replace html when template root element is table row (tr)